typedef struct {
    int k;
    int front;
    int rear;
    int* a;
}CircularQueue;

CircularQueue* CircularQueueCreate(int k) {
    CircularQueue* obj = (CircularQueue*)malloc(sizeof(CircularQueue));
    obj->a = (int*)malloc((k + 1) * sizeof(int));
    obj->front = obj->rear = 0;
    obj->k = k;

    return obj;
}

bool CircularQueueIsEmpty(CircularQueue* obj) {
    return obj->front == obj->rear;
}

bool CircularQueueIsFull(CircularQueue* obj) {
    return (obj->rear + 1) % (obj->k + 1) == obj->front;
}

bool CircularQueueEnQueue(CircularQueue* obj, int value) {
    if (CircularQueueIsFull(obj))
        return false;
    obj->a[obj->rear] = value;
    obj->rear = (obj->rear + 1) % (obj->k + 1);

    return true;
}

bool CircularQueueDeQueue(CircularQueue* obj) {
    if (CircularQueueIsEmpty(obj))
        return false;
    obj->front = (obj->front + 1) % (obj->k + 1);

    return true;
}

int CircularQueueFront(CircularQueue* obj) {
    if (CircularQueueIsEmpty(obj))
        return -1;
    return obj->a[obj->front];
}

int CircularQueueRear(CircularQueue* obj) {
    if (CircularQueueIsEmpty(obj))
        return -1;

    return obj->a[(obj->rear + obj->k) % (obj->k + 1)];
}

void CircularQueueFree(CircularQueue* obj) {
    free(obj->a);
    free(obj);
}
/*
*
* Your CircularQueue struct will be instantiated and called as such:
* CircularQueue* obj = CircularQueueCreate(k);
* bool param_1 = CircularQueueEnQueue(obj, value);
* bool param_2 = CircularQueueDeQueue(obj);
* int param_3 = CircularQueueFront(obj);
* int param_4 = CircularQueueRear(obj);
* bool param_5 = CircularQueueIsEmpty(obj);
* bool param_6 = CircularQueueIsFull(obj);
* CircularQueueFree(obj);
*/